using System;
using System.Collections.Generic;
using S2Engine.Audio;
using S2Engine.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using S2Engine.Input.Xbox360;
using S2Engine.Game;


namespace S2Engine.Timeline
{
    /// <summary>
    /// Uma unidade no espaco do tempo do jogo, cada nivel
    /// </summary>
    public class Scene2D : IScene
    {
        #region Attributes
        protected Color backcolor = Color.Black;
        private string name;
        private S2Game game;
        protected static S2Game staticGame;
        private int index;
        private bool disposed;
        private bool paused;
        protected bool ready;
       // private SpriteBatch batch;
        protected Keyboard Keyboard = new Keyboard();
        

        protected GamePad Controller0;
        protected GamePad Controller1;
        protected GamePad Controller2;
        protected GamePad Controller3;

        //protected  List<S2Engine.S2D.Sprite> sprites = new List<S2Engine.S2D.Sprite>();
        //private List<S2Engine.S2D.Sprite> addedSprites = new List<S2Engine.S2D.Sprite>();
        //private List<S2Engine.S2D.Sprite> deletedSprites = new List<S2Engine.S2D.Sprite>();
        //private List<S2Engine.S2D.Sprite> zOrderedSprites = new List<S2Engine.S2D.Sprite>();

        protected List<Cue> Sounds = new List<Cue>();
        //private List<S2Engine.Text.FontManager> fonts = new List<S2Engine.Text.Font>();

        
        #endregion

        #region Ctor
        public Scene2D(S2Game game, string name)
        {
            this.game = game;
            staticGame = game;
            this.name = name;
           // batch = new SpriteBatch(game.Graphics.GraphicsDevice);
        }
        #endregion

        #region Events
        public event EventHandler BeforeRendering;
        public event EventHandler AfterRendering;
        public event EventHandler Rendering;
        public event EventHandler InputChecking;
        public event EventHandler BeforeLoad;
        public event EventHandler Loading;
        public event EventHandler Loaded;
        public event PauseEventHandler Pause;
        public event EventHandler Rendered;

        protected virtual void OnRendered(EventArgs e)
        {
            if (Rendered != null)
                Rendered(this, e);
        }

        protected virtual void OnLoaded(EventArgs e)
        {
            if (Loaded != null)
                Loaded(this,e);
        }
        protected virtual void OnLoading(EventArgs e)
        {
            if (Loading != null)
                Loading(this,e);
        }

        protected virtual void OnBeforeLoad(EventArgs e)
        {
            if (BeforeLoad != null)
                BeforeLoad(this,e);
        }

        protected virtual void OnPause(PauseEventArgs e)
        {
            if (Pause != null)
                Pause(e);
        }

        protected virtual void OnInputChecking(EventArgs e)
        {
            if (InputChecking != null)
                InputChecking(this, e);
        }

        protected virtual void OnRendering(EventArgs e)
        {
            if (Rendering != null)
                Rendering(this, e);
        }

        protected virtual void OnBeforeRendering(EventArgs e)
        {
            if (BeforeRendering != null)
                BeforeRendering(this, e);
        }
        protected virtual void OnAfterRendering(EventArgs e)
        {
            if (AfterRendering != null)
                AfterRendering(this, e);
        }
        #endregion

        #region Properties
        //public List<Picture> Pictures
        //{
        //    get { return pictures; }
        //}
        //public List<Sprite> Sprites
        //{
        //    get { return sprites; }
        //}
        //public SpriteBatch Batch
        //{
        //    get { return batch; }
        //}

        public Vector2 Position
        {
            get { return Vector2.Zero; }
            set { }
        }
        public Color BackColor
        {
            get { return backcolor; }
        }
        public bool Ready
        {
            get { return ready; }
        }
        public string Name
        {
            get { return name; }
        }

        public bool Paused
        {
            get { return paused; }
            set { paused = value; }
        }

        public bool Visible
        {
            get
            {
                return true;
            }
            set
            {
                
            }
        }

       public int Index
        {
            get
            {
                return index;
            }
            set
            {
                index = value;
            }
        }

        public S2Game Game
        {
            get
            {
                return game;
            }
        }

        public bool Disposed
        {
            get { return disposed; }
            set { disposed = value; }
        }
        #endregion

        #region Methods
        public void AfterRender()
        {
            OnAfterRendering(EventArgs.Empty);
        }
        public void BeforeRender()
        {
            OnBeforeRendering(EventArgs.Empty);
        }

        public void InputCheck()
        {
            this.Keyboard.Update();
            if(Controller0 != null)
            if (Controller0.IsConnected)
                Controller0.Update();
            OnInputChecking(EventArgs.Empty);
        }

        public void PauseGame()
        {
            paused = !paused;
            OnPause(new PauseEventArgs(paused));
        }

        //public void Add(Sprite sprite)
        //{
        //    sprite.Disposed +=new SpriteEventHandler(sprite_Disposed);
        //    addedSprites.Add(sprite);
        //}

        /// <summary>
        /// Releases all resources useds by scene
        /// </summary>
        public virtual void Dispose()
        {
            ready = false;
            //foreach (Picture picture in pictures)
            //    picture.Dispose();
            //pictures.Clear();

            //foreach (S2Engine.Text.Font font in fonts)
            //    font.Dispose();
            //fonts.Clear();

            //foreach (Sound sound in Sounds)
            //    sound.Dispose();
            Sounds.Clear();

            disposed = true;

        }

        /// <summary>
        /// Renderiza todos os Labels e Sprites da cena
        /// </summary>
        public virtual void Draw()
        {
            if (!ready)
                return;
            

           // batch.Begin(SpriteBlendMode.AlphaBlend);
            OnRendering(EventArgs.Empty);
            //foreach (Label label in labels)
            //    label.Render();

            //sprites.Sort(S2Engine.S2D.Sprite.ComparisonZOrder);

           // foreach (S2Engine.S2D.Sprite sprite in sprites)
                //sprite.Draw();

            //foreach (SceneComponent component in Components)
            //    component.Draw();

            //foreach (Label label in Labels)
               // label.Render();
           // batch.End();

        }

        /// <summary>
        /// Atualiza as colecoes de objetos da Cena
        /// </summary>
        public virtual void Update()
        {
            if (!ready)
                return;

            //foreach (S2Engine.S2D.Sprite s in addedSprites)
            //{
            //   // s.Disposed += new SpriteEventHandler(s_Disposed);
            //    sprites.Add(s);
            //    zOrderedSprites.Add(s);
            //}
            //addedSprites.Clear();
/*
            foreach (S2Engine.S2D.Sprite s in deletedSprites)
            {
                sprites.Remove(s);
               zOrderedSprites.Remove(s);
            }
            deletedSprites.Clear();*/

            //foreach (S2Engine.S2D.Sprite s in sprites)
            //    s.InternalUpdate();

            //foreach (S2Engine.S2D.Sprite s in prites)
                //s.InternalUpdate();

            //if(!paused)
            //foreach (SceneComponent component in Components)
            //    component.Update();

            /*
            foreach (Label t in addedLabels)
                Labels.Add(t);
            addedLabels.Clear();

            foreach (Label t in deletedLabels)
                Labels.Remove(t);
            deletedLabels.Clear();*/

            //foreach (Label t in labels)
               // t.up
        }

        //void sprite_Disposed(Sprite e)
        //{
        //    deletedSprites.Add(e);
        //}

        ///// <summary>
        ///// Retorna a colecao de Sprites que colidem com um Sprite
        ///// </summary>
        ///// <param name="sprite">Sprite a ser analisada</param>
        ///// <returns></returns>
        //public List<S2Engine.S2D.Sprite> GetCollidedSprites(S2Engine.S2D.Sprite sprite)
        //{
        //    List<S2Engine.S2D.Sprite> collisionList = new List<S2Engine.S2D.Sprite>();
        //    foreach (S2Engine.S2D.Sprite s in sprites)
        //    {
        //        if (s != sprite && s.CollidesWith(sprite))
        //            collisionList.Add(s);
        //    }

        //    if (collisionList.Count != 0)
        //        return collisionList;
        //    return null;
        //}

        /// <summary>
        /// Inicia a Cena
        /// </summary>
        public virtual void Start()
        {
            
            //ReadXmlFile();
        }

        /// <summary>
        /// Para a execucao da Cena
        /// </summary>
        public virtual void Stop()
        {

        }

        public virtual void Load()
        {
            OnBeforeLoad(EventArgs.Empty);
            Controller0 = new GamePad(PlayerIndex.One);
            Controller1 = new GamePad(PlayerIndex.Two);
            Controller2 = new GamePad(PlayerIndex.Three);
            Controller3 = new GamePad(PlayerIndex.Four);
            OnLoading(EventArgs.Empty);
        }

  
        #endregion
    }
}
